/*
Kakine
ActionScript Framework
Copyright © 2011, PUNY, LLC.

This file is part of KAKINE.

KAKINE is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

KAKINE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with KAKINE.  If not, see <http://www.gnu.org/licenses/>.
*/ 
package com.puny.mvc.views
{
//	import com.puny.gm.tw.utils.AtomicBitmap;
	import com.puny.mvc.controllers.ComboBox;
	import com.puny.mvc.models.Model;
	import com.puny.utils.ObjectFinder;
	
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	
	/**
	 * This view is for a ComboBox. In this framework, a combo box consits of 4 exported <code>MovieClip</code>, <code>List</code>, <code>Slider</code>, <code>Thumb</code>, and <code>TextForList</code>.
	 * To populate values in a list, an xml is required.
	 * 
	 * @author puny
	 * 
	 * @private
	 */
	public class ComboBoxView extends View
	{
		private const PLATE:Sprite = new Sprite();
		private var _selectedField:MovieClip;
		private var _listBack:MovieClip;
		private var _slider:MovieClip;
		private var _thumb:MovieClip;
		private var _itemXML:XML;
		private var _slideRect:Rectangle;
		private var _model:Model;
		private var _index:int;
		public function ComboBoxView(src:Object, xml:XML, model:Model)
		{
			_itemXML = xml;
			this.model = model;
			super(src);
		}
		
		override protected function setup():void {
			_listBack = getMovieClip("List") as MovieClip;
			_listBack.width = _itemXML.@width;
			PLATE.mask = _listBack.addChild(getMovieClip("List")) as MovieClip;
			(PLATE.mask as MovieClip).removeChild(ObjectFinder.find(PLATE.mask as MovieClip, "Slider"));
			(PLATE.mask as MovieClip).removeChild(ObjectFinder.find(PLATE.mask as MovieClip, "Thumb"));
			_selectedField = getMovieClip("TextForList") as MovieClip;
//			(_selectedField.getChildAt(0) as TextField).background = true;
//			(_selectedField.getChildAt(0) as TextField).backgroundColor = 0xFF0000;
			(_selectedField.getChildAt(0) as TextField).width = _listBack.width;
			(_selectedField.getChildAt(0) as TextField).height = 20;
			(_selectedField.getChildAt(0) as TextField).selectable = false;
			_selectedField.y = 2;
//			var format:TextFormat = (_selectedField.getChildAt(0) as TextField).defaultTextFormat;
//			format.align = TextFormatAlign.CENTER;
//			(_selectedField.getChildAt(0) as TextField).defaultTextFormat = format;
//			var filter:DisplacementMapFilter = new AtomicBitmap().filter;
//			var pt:Point = filter.mapPoint;
//			if (_itemXML.hasOwnProperty("@index")) {
//				pt.x = -110 * int(_itemXML.@index);
//			}
//			filter.mapPoint = pt;
//			_selectedField.filters = [filter];
			var child:MovieClip;
			var first:Boolean = true;
			for each(var item:XML in _itemXML.elements()) {
				child = PLATE.addChild(getMovieClip("TextForList")) as MovieClip;
				(child.getChildAt(0) as TextField).width = _listBack.width;
				(child.getChildAt(0) as TextField).selectable = false;
				child.addEventListener(MouseEvent.ROLL_OUT, textOutHandler);
				child.addEventListener(MouseEvent.ROLL_OVER, textOverHandler);
				child.addEventListener(MouseEvent.CLICK, textClickedHandler);
				child.index = PLATE.numChildren-1;
				child.x = 5;
				child.y = child.height * child.index;
				child.scaleX = 1/_listBack.scaleX;
				(child.getChildAt(0) as TextField).text = item.toString();				
			}
			_slider = ObjectFinder.find(_listBack, "Slider") as MovieClip;
//			_slider.visible = false;
			_thumb = ObjectFinder.find(_listBack, "Thumb") as MovieClip;
			_thumb.scaleX = 1/_listBack.scaleX;
			_slider.width = _thumb.width;
			useHandCursor = true;
			
			if ( PLATE.height <= _listBack.height) {
				_slider.visible = false;
				_thumb.visible = false;
				_listBack.height = PLATE.height;
				PLATE.scaleY = 1/_listBack.scaleY;
			}
			
		}
		
		override public function beforeReady():void {
			addChild(_selectedField);
			_selectedField.addEventListener(MouseEvent.CLICK, openHandler);
			_selectedField.x += 5;
			
			addChild(_listBack);
			_listBack.y = _selectedField.height;
			_listBack.addChildAt(PLATE, _listBack.getChildIndex(_slider));
			
			_thumb.y = _slider.y;
			_thumb.addEventListener(MouseEvent.MOUSE_DOWN, startDragHandler);
			stage.addEventListener(MouseEvent.MOUSE_UP, stopDragHandler);

			_slideRect = _slider.getBounds(_listBack);
			_slideRect.x = _thumb.x;
			_slideRect.width = 0;
			_slideRect.height -= _thumb.height;
			
			_listBack.visible = false;
		}
				
		override public function beforeClose():void {
			for (var i:int = 0; i < PLATE.numChildren; i++) {
				PLATE.getChildAt(i).removeEventListener(MouseEvent.ROLL_OUT, textOutHandler);
				PLATE.getChildAt(i).removeEventListener(MouseEvent.ROLL_OVER, textOverHandler);
				PLATE.getChildAt(i).removeEventListener(MouseEvent.CLICK, textClickedHandler);
			}

			_model.removeEventListener(ComboBox.SELECTED, updateTextHandler);
			_thumb.removeEventListener(MouseEvent.MOUSE_DOWN, startDragHandler);
			stage.removeEventListener(MouseEvent.MOUSE_UP, stopDragHandler);
		}
		
		private function updateTextHandler(event:Event):void {
			(_selectedField.getChildAt(0) as TextField).text = _model.selected;
		}
		
		private function openHandler(event:Event):void {
			_listBack.visible = true;
			_selectedField.removeEventListener(MouseEvent.CLICK, openHandler);
			stage.addEventListener(MouseEvent.CLICK, cancelHandler);
		}
		
		private function cancelHandler(event:MouseEvent):void {
			var pt:Point = globalToLocal(new Point(event.stageX, event.stageY));
			if (pt.x < 0 || pt.x > _listBack.width ||
				pt.y < 0 || pt.y > _listBack.y + PLATE.mask.height) {
					closeHandler(event);
			}
		}
				
		private function closeHandler(event:Event):void {
			if (stage != null) {
				stage.removeEventListener(MouseEvent.CLICK, cancelHandler);
				_selectedField.addEventListener(MouseEvent.CLICK, openHandler);
				_listBack.visible = false;
			}
		}
		
		private function textOutHandler(event:Event):void {
			var text:TextField = event.currentTarget.getChildAt(0) as TextField;
			text.background = false;
		}
		
		private function textOverHandler(event:Event):void {
			var text:TextField = event.currentTarget.getChildAt(0) as TextField;
			text.backgroundColor = 0xF8B7C8;
			text.background = true;
		}
		
		private function textClickedHandler(event:Event):void {
			_model.id = event.currentTarget.index;
			_model.selected = event.currentTarget.getChildAt(0).text;
			closeHandler(event);
		}
		
		private function startDragHandler(event:Event):void {
			_thumb.startDrag(false, _slideRect);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, sliderHandler);
		}
		
		private function sliderHandler(event:Event):void {
			if (PLATE.height > _slideRect.height) {
				PLATE.y = -_thumb.y * (PLATE.height / _slideRect.height - 1);
			}
		}
		
		private function stopDragHandler(event:Event):void {
			_thumb.stopDrag();
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, sliderHandler);
		}
		
		public function addItems(xml:XML):void {
			_itemXML = xml;
		}
		
		public function set model(value:Model):void {
			if (_model != null) {
				_model.removeEventListener(ComboBox.SELECTED, updateTextHandler);
			}
			_model = value;
			_model.addEventListener(ComboBox.SELECTED, updateTextHandler);
		}
	}
}